/*
 * =====================================================================================
 *
 *       Filename:  sunday_str_search.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  11/26/2010 09:39:08 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Ken Chen (Ken), chen_kenz@emc.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#include "sunday_str_search.h"
#include <cstring>
#include <iostream>
using namespace std;

Sunday::Sunday( const char* txt, const char* pattern )
  : m_text(txt),
  m_pattern(pattern),
  m_txtLength(-1),
  m_patLength(-1)
{
  if( m_text != NULL )
  {
    m_txtLength = strlen( m_text );
  }

  if( m_pattern != NULL )
  {
    m_patLength = strlen( m_pattern );
    preprocessPatternStr();
  }
}

Sunday::~Sunday()
{
}

const char* Sunday::find( void ) const
{
  if( (m_txtLength <= 0) || (m_patLength <= 0) )
  {
    return NULL;
  }

  const char* pat = m_pattern;
  const char* txt = m_text;
  for( ; (m_text + m_txtLength - txt) >= m_patLength; ) 
  {
    if( strnCompare( txt, pat, m_patLength ) == 0 ) 
    {
      return txt;
    }
    else
    {
      txt += m_steppers[txt[m_patLength]];
    }
  }
  return NULL;
}

void Sunday::preprocessPatternStr( void )
{
  for( int i=0; i < sizeof(m_steppers)/sizeof(m_steppers[0]); ++i )
  {
    m_steppers[i] = m_patLength + 1;
  }

  const char* p = m_pattern; 
  int step = m_patLength;

  for( ; *p; ++p, --step )
  {
    m_steppers[*p] = step;
  }
}

int Sunday::strnCompare( const char* s1, const char* s2, int len )
{
  return strncmp( s1, s2, len );
}

int main( int argc, char* argv[] )
{
  const char* text = "csdn.blog.csdn,blog.net";
  const char* pat = "csdn,blog";

  Sunday sun( text, pat );
  const char* p = sun.find();
  if( p != NULL )
  {
    cout << p << endl;
  }

  return 0;
}

